package com.egoo.ticket.server.config.redis;

import com.egoo.ticket.server.service.TriggerExecuteService;
import com.egoo.ticket.server.utils.common.ConstantCode;
import com.egoo.ticket.server.utils.common.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author Administrator
 * @Date: 2020/1/3 14:34
 * @Description: redis过期key监听类
 */
@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
	@Autowired
	private RedisTemplate redisTemplate;

	@Autowired
	private RedisUtil redisUtil;

	@Autowired
	private TriggerExecuteService triggerExecuteService;

	public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
		super(listenerContainer);
	}

	@Override
	public void onMessage(Message message, byte[] pattern) {
		String expiredKey = message.toString();
		log.info("过期的key是: " + expiredKey);

		// 添加过期key锁，解决集群部署，监听重复处理问题，避免redis内存溢出
		String lockKey = expiredKey + "_lock";
		String lockValue = redisUtil.getAndSet(lockKey, "Y");
		log.info("过期锁" + lockKey + "的值为：" + lockValue);
		if (ConstantCode.Y.equals(lockValue)) {
			return;
		}
		try {
			String[] expiredKeyArray = expiredKey.split("_");
			String workOrderId = expiredKeyArray[expiredKeyArray.length - 1];

			if (expiredKey.contains(RedisKeyConstant.WORK_ORDER_CREATE_TIME_PREFIX)
					|| expiredKey.contains(RedisKeyConstant.WORK_ORDER_CLOSE_TIME_PREFIX)
			) {
				log.info("触发器执行工单id为：" + workOrderId);
				// 工单触发器执行
				triggerExecuteService.triggerExecuteByWorkOrderId(workOrderId);
			}

			else if(expiredKey.contains(RedisKeyConstant.WORK_ORDER_CALL_TIME_PREFIX)){
				log.info("预约回电提醒工单id为：" + workOrderId);
				// 预约回电提醒
				triggerExecuteService.handlePrepareToWarnPhoneBusi(workOrderId);
			}
		} catch (Exception e) {
			log.error("触发器 redis过期key消息：" + message + "执行异常：" + e);
		} finally {
			// 业务处理完，删除订阅锁，避免redis内存溢出和业务混乱
			redisUtil.del(lockKey);
		}

	}
}
